Imports System.Drawing.Imaging
Imports Microsoft.DirectX
Imports Microsoft.DirectX.Direct3D

Imports System.Threading
Imports System.Runtime.InteropServices

Namespace Engine

    Module mEngine

        Friend Declare Auto Function PeekMessage Lib "user32.dll" ( _
            ByRef lpMsg As MessageStruct, _
            ByVal hWnd As IntPtr, _
            ByVal wMsgFilterMin As Integer, _
            ByVal wMsgFilterMax As Integer, _
            ByVal wRemoveMsg As Integer _
        ) As Boolean

        <StructLayout(LayoutKind.Sequential)> _
        Public Structure MessageStruct
            Public HWnd As IntPtr
            Public Msg As Integer
            Public WParam As IntPtr
            Public LParam As IntPtr
            Public Time As Integer
            Public P As System.Drawing.Point
        End Structure

        Dim threadGame As Thread

        Public CurrentFPS As Double
        Public CurrentDataIn As Single
        Public CurrentDataOut As Single
        Public CurrentPing As Single

        Public LosingConnection As Boolean

        'Public Sub StartGameLoop()

        'threadGame = New Thread(AddressOf GameLoop)
        'threadGame.Start()

        'GameLoop()

        'End Sub

        Public Sub GameLoop(ByRef ip As String, ByRef port As Integer)

            Randomize()

            If My.Application.CommandLineArgs.Count > 0 Then
                If My.Application.CommandLineArgs(0) = "-R" And DirectX.Windowed Then
                    Globals.fGameForm.Left = My.Computer.Screen.WorkingArea.Width - Constants.gGameResX
                    Globals.fGameForm.Top = My.Computer.Screen.WorkingArea.Height - Constants.gGameResY
                End If
            End If

            Application.DoEvents()

            Sound.Init()
            DirectX.Init()
            Libs.Init()
            MessageBoxes.Init()
            Mouse.Init()

            'MessageBoxes.SetStateNotice("Connecting...")

            If System.Net.IPAddress.TryParse(ip, Nothing) Then
                ClientSock.ConnectTo(System.Net.IPAddress.Parse(ip), port)
            Else
                ClientSock.ConnectTo(ip, port)
            End If

            Auth.Init()


            Do Until Globals.bEnding

                Mouse.DoInputs()
                Keyboard.DoInputs()
                Sound.DoSound()

                If DirectX.DeviceLost Then
                    DirectX.DeviceRecovery()
                End If

                If Not DirectX.DeviceLost Then

                    If Globals.gGameState = Globals.GameState.Game Then
                        'Debug.Print("")
                    End If

                    ClientSock.Poll()

                    Try
                        DrawGame()
                    Catch ex As Microsoft.DirectX.Direct3D.DeviceLostException
                        DirectX.DeviceLost = True
                    Catch ex As Microsoft.DirectX.Direct3D.DeviceNotResetException
                        DirectX.DeviceLost = True
                    End Try

                    Timers.DoTimers()

                End If

                If Not AppIsIdle() Then
                    Try
                        Application.DoEvents()
                    Catch ex As Exception
                    End Try
                End If

            Loop

            Select Case Globals.gGameState
                Case Globals.GameState.Auth
                    Auth.Shutdown()
                Case Globals.GameState.SelChar
                    SelectChar.Shutdown()
                Case Globals.GameState.Game
                    Game.Shutdown()
            End Select

            Libs.Shutdown()
            Sound.Shutdown()
            ClientSock.Shutdown()
            DirectX.Shutdown()

            Application.Exit()
            System.Environment.Exit(System.Environment.ExitCode)

        End Sub

        Private Sub DrawGame()

            If Globals.gGameState = Globals.GameState.Game Then
                If Not Game.IsInGame Then
                    Exit Sub
                Else
                    Player.DoMove()
                End If
            End If

            'measures Frame Count and Ticks for FPS counter
            Static Dim iFrames As Integer, iFrameTicks As Long
            'measure Ticks for Data rate
            Static Dim iDataTicks As Long
            'measure ticks to help with measuring Ping
            Static Dim iPingTicks As Long

            'If Globals.gGameState = Globals.GameState.Game Then

            Windows.DrawWindows(Globals.DrawingMode.Overlay)

            'End If

            'DirectX.D3D.VertexFormat = DirectX.FVF_CUSTVERT

            DirectX.D3D.SetRenderTarget(0, DirectX.GameSurface)

            DirectX.D3D.Clear(ClearFlags.Target Or ClearFlags.ZBuffer, Color.Black, 1.0F, 0)

            DirectX.D3D.BeginScene()

            DirectX.GameSprite.Begin(SpriteFlags.AlphaBlend)
            Engine.SetDrawModeNormal(1.0, Color.White)
            Windows.DrawWindows(Globals.DrawingMode.Normal)
            MessageBoxes.DrawStateNotice(Globals.DrawingMode.Normal)
            GUI.MouseDragItem.DrawMouseDragItem(Globals.DrawingMode.Normal)
            DirectX.GameSprite.End()


            Windows.DrawWindows(Globals.DrawingMode.Shadow)
            'MessageBoxes.DrawStateNotice(Globals.DrawingMode.Normal)

            DirectX.GameSprite.Begin(SpriteFlags.AlphaBlend)
            Engine.SetDrawModeNormal(0.7, Color.White)
            Windows.DrawWindows(Globals.DrawingMode.SemiTransparent)
            'MessageBoxes.DrawStateNotice(Globals.DrawingMode.Normal)
            'Libs.EvoInterface.Image(10).Draw(Mouse.XCoord, Mouse.YCoord, 0.0)
            DirectX.GameSprite.End()

            DirectX.GameSprite.Begin(SpriteFlags.AlphaBlend)
            Engine.SetDrawModeGrayscale(1.0, Color.White)
            Windows.DrawWindows(Globals.DrawingMode.Grayscale)
            'MessageBoxes.DrawStateNotice(Globals.DrawingMode.Normal)
            DirectX.GameSprite.End()

            Windows.DrawWindows(Globals.DrawingMode.Tinted)
            GUI.MouseDragItem.DrawMouseDragItem(Globals.DrawingMode.Tinted)
            'MessageBoxes.DrawStateNotice(Globals.DrawingMode.Normal)

            DirectX.GameSprite.Begin(SpriteFlags.AlphaBlend)
            Engine.SetDrawModeMagic(1.0, Color.White)
            MessageBoxes.DrawStateNotice(Globals.DrawingMode.Magic)
            Windows.DrawWindows(Globals.DrawingMode.Magic)
            DirectX.GameSprite.End()

            Windows.DrawWindows(Globals.DrawingMode.Line)

            'draws a red box around the border of the screen incase we are loosing connection
            If LosingConnection Then

                DrawBox(0, DirectX.DispMode.Width - 1, 0, DirectX.DispMode.Height - 1, 0.001F, 1, Color.Red)

            End If


            DirectX.D3D.EndScene()

            'Engine.UseLineShader()
            'DirectX.D3D.VertexFormat = DirectX.FVF_LINEVERT

            Engine.ResetShader()

            Engine.SetDrawModeNormal(1.0, Color.White)
            MessageBoxes.DrawStateNotice(Globals.DrawingMode.Text)
            Windows.DrawWindows(Globals.DrawingMode.Text)

            If Globals.DEBUG_SHOWTEXT Then

                'Draw fps count
                'DirectX.ProFont9.DrawBoldBorderText(iFPS.ToString, 2, 2, Color.Red, Color.White, 0.001F)
                DirectX.ProFont9.DrawBorderText("   FPS> " & FormatNumber(Engine.CurrentFPS, 2), 10, 10, Color.White, Color.Red, 0.001F)
                DirectX.ProFont9.DrawBorderText("  Ping> " & FormatNumber(Engine.CurrentPing, 0) & " [ms]", 10, 10 + DirectX.ProFont9.GetNormalTextHeight("X"), Color.White, Color.Red, 0.001F)
                DirectX.ProFont9.DrawBorderText("    In> " & FormatNumber(Engine.CurrentDataIn, 0) & " [bytes/s]", 10, 10 + DirectX.ProFont9.GetNormalTextHeight("X") * 2, Color.White, Color.Red, 0.001F)
                DirectX.ProFont9.DrawBorderText("   Out> " & FormatNumber(Engine.CurrentDataOut, 0) & " [bytes/s]", 10, 10 + DirectX.ProFont9.GetNormalTextHeight("X") * 3, Color.White, Color.Red, 0.001F)
                DirectX.ProFont9.DrawBorderText(" DEBUG> IDX: (" & Globals.DEBUG_IDX & ")   X: (" & Globals.DEBUG_X(Globals.DEBUG_IDX) & ")   Y: (" & Globals.DEBUG_Y(Globals.DEBUG_IDX) & ")", 10, 10 + DirectX.ProFont9.GetNormalTextHeight("X") * 4, Color.White, Color.Red, 0.001F)

            End If

            'Engine.SetDrawModeLights(Color.Black)
            'GameWindow.DrawLightsOverlay()
            If Globals.gGameState = Globals.GameState.Game Then GameWindow.DrawLights()

            DirectX.D3D.BeginScene()

            DirectX.GameSprite.Begin(SpriteFlags.AlphaBlend)
            Engine.SetDrawModeNormal(1.0, Color.White)
            Windows.DrawWindows(Globals.DrawingMode.Tooltip)
            DirectX.GameSprite.End()

            'Engine.UseLineShader()
            'DirectX.D3D.VertexFormat = DirectX.FVF_LINEVERT


            DirectX.D3D.EndScene()

            Try
                DirectX.D3D.Present()
            Catch e As Microsoft.DirectX.Direct3D.DeviceLostException
                DirectX.DeviceLost = True
            End Try


            'Current Clock Ticks
            Dim tc As Long = DateTime.Now.Ticks

            'Setup initial Clock Ticks measurement vars
            If iFrameTicks = 0 Then
                iFrameTicks = tc
                iDataTicks = tc + 10000000
                iPingTicks = tc + 25000000
            End If

            'Increase framecount by 1
            iFrames += 1

            'measure FPS & Data IO Rates every 1/10 second, measure an eaxct ratio for the period to get greater accuracy in results
            If iFrameTicks + 2000000 < tc Then

                'Calculate the ratio of frames to seconds
                Dim ratio As Double = (1000 / (((tc - iFrameTicks) / 100) / 100))
                'Multiply the FrameCount by the calculated ratio to give a Frame Count based as per Second
                CurrentFPS = (iFrames * ratio)

                iFrameTicks = tc
                iFrames = 0

                'garbage collector
                'GC.Collect()

                'Globals.fGameForm.Text = iFPS.ToString
            End If

            'measure data rates every 1 second, no need for ratio's as this is a whole per second measurement
            If iDataTicks < tc Then

                CurrentDataIn = ClientSock.gSock.INbytes
                CurrentDataOut = ClientSock.gSock.OUTbytes

                ClientSock.gSock.INbytes = 0
                ClientSock.gSock.OUTbytes = 0

                iDataTicks = tc + 10000000

            End If

            'measure ping
            If iPingTicks < tc Then

                'send PingTest.Notify EvoLib.Protocol.Packet
                Ping(tc)
                'set Ping Ticks measurement to current Clock Ticks
                iPingTicks = tc + 25000000

                'remove everything outside of the Playing Area:
                Mobs.FilterMobs() 'remove excess mobs
                Characters.FilterCharacters() 'remove excess characters
                FloorItems.FilterFloorItems() 'remove excess floor items
                NPCs.FilterNPCs()

            End If

        End Sub

        Private PingAt As Long

        Public Sub Ping(ByRef tc As Long)

            'if previous PING has recieved its corresponding PONG (PingAt=0) or we have been wait for PONG over 7.5 seconds
            If PingAt = 0 Or PingAt + 75000000 < tc Then

                'Send PingTest.Notify EvoLib.Protocol.Packet
                Dim pkt As EvoLib.Protocol.Packet
                pkt.PacketType = EvoLib.Protocol.GenericPacketType.PingTest
                pkt.PacketOpCode = EvoLib.Protocol.PacketOpCode.Notify
                pkt.Username = Globals.sUsername

                ClientSock.SendData(EvoLib.Protocol.MakePacket(pkt, , Globals.Crypto))

                'store clock tick count to calculate PING
                PingAt = tc

            Else

                'we are having to wait too long for the PONG EvoLib.Protocol.Packet, set LosingConnection flag
                LosingConnection = True

            End If

        End Sub

        Public Sub Pong()

            'measure clock ticks
            Dim PongAt As Long = DateTime.Now.Ticks

            'calculate how long after ping was sent, pong was recieved, i.e. Calculate Latencey
            Dim P As Long = PongAt - PingAt
            'divide P by 10000 Ticks to give us a measurement in milliseconds
            CurrentPing = P / 10000

            'discard PingAt Clock Tick count
            PingAt = 0

            'set LosingConnection flag to false
            LosingConnection = False

        End Sub


        Public Sub DrawLineEx(ByVal X1 As Integer, ByVal X2 As Integer, ByVal Y1 As Integer, ByVal Y2 As Integer, ByRef z As Single, ByRef Width As Integer, ByRef Colour As System.Drawing.Color)

            'DirectX.GameSprite.End()

            Dim aLineVertex As CustomVertex.TransformedColored() = New CustomVertex.TransformedColored(0 To 1) {}
            'Set the starting point of the line
            aLineVertex(0).Position = New Vector4(X1, Y1, z, 0)
            aLineVertex(0).Color = Colour.ToArgb

            'Set the ending point of the line
            aLineVertex(1).Position = New Vector4(X2, Y2, z, 0)
            aLineVertex(1).Color = Colour.ToArgb

            'Render the line
            'DirectX.D3D.SetTexture(0, Nothing)

            '    UseLineShader()

            Try

                DirectX.D3D.DrawUserPrimitives(PrimitiveType.LineList, 1, aLineVertex)

            Catch ex As Microsoft.DirectX.Direct3D.DeviceLostException

            Catch ex As Microsoft.DirectX.Direct3D.DeviceNotResetException

            End Try

        End Sub

        Public Sub DrawLine(ByVal X1 As Integer, ByVal X2 As Integer, ByVal Y1 As Integer, ByVal Y2 As Integer, ByRef z As Single, ByRef Width As Integer, ByRef Colour As System.Drawing.Color)

            DirectX.GameLine.Width = Width
            DirectX.GameLine.Begin()

            Dim V3() As Vector3 = {New Vector3(X1, Y1, z), New Vector3(X2, Y2, z)}

            Dim mtrix As Matrix = Matrix.Multiply(DirectX.D3D.Transform.World, DirectX.D3D.Transform.View)
            mtrix = Matrix.Multiply(mtrix, DirectX.D3D.Transform.Projection)

            DirectX.GameLine.DrawTransform(V3, mtrix, Colour)

            DirectX.GameLine.End()

        End Sub

        Public Sub DrawBox(ByRef rect As Rectangle, ByRef z As Single, ByRef width As Integer, ByRef colour As Color)
            DrawBox(rect.Left, rect.Right, rect.Top, rect.Bottom, z, width, colour)
        End Sub

        Public Sub DrawBox(ByRef X1 As Integer, ByRef X2 As Integer, ByRef Y1 As Integer, ByRef Y2 As Integer, ByRef z As Single, ByRef Width As Integer, ByRef Colour As System.Drawing.Color)

            DrawLine(X1, X1, Y1, Y2, z, Width, Colour)
            DrawLine(X2, X2, Y1, Y2, z, Width, Colour)
            DrawLine(X1, X2, Y1, Y1, z, Width, Colour)
            DrawLine(X1, X2, Y2, Y2, z, Width, Colour)

        End Sub

        Public Sub DrawSolidBox(ByRef rect As Rectangle, ByRef z As Single, ByRef colour As Color)
            DrawSolidBox(rect.Left, rect.Right, rect.Top, rect.Bottom, z, colour)
        End Sub

        Public Sub DrawSolidBox(ByRef X1 As Integer, ByRef X2 As Integer, ByRef Y1 As Integer, ByRef Y2 As Integer, ByRef z As Single, ByRef colour As System.Drawing.Color)

            Dim tmpInt As Integer
            If X1 > X2 Then
                tmpInt = X1
                X1 = X2
                X2 = tmpInt
            End If
            If Y1 > Y2 Then
                tmpInt = Y1
                Y1 = Y2
                Y2 = tmpInt
            End If

            Dim height As Integer = Y2 - Y1
            If height = 0 Then height = 1
            Dim Y As Integer = Y1 + (height / 2)

            DirectX.GameLine.Width = height

            DirectX.GameLine.Begin()

            Dim mtrix As Matrix = Matrix.Multiply(DirectX.D3D.Transform.World, DirectX.D3D.Transform.View)
            mtrix = Matrix.Multiply(mtrix, DirectX.D3D.Transform.Projection)

            Dim V3() As Vector3 = {New Vector3(X1, Y, z), New Vector3(X2, Y, z)}

            DirectX.GameLine.DrawTransform(V3, mtrix, colour)
            DirectX.GameLine.End()

        End Sub

        '    Dim aLineVertex As CustomVertex.TransformedColored() = New CustomVertex.TransformedColored(0 To 4) {}

        '    aLineVertex(0).Position = New Vector4(X1, Y1, z, 0)
        '    aLineVertex(0).Color = colour.ToArgb

        '    aLineVertex(1).Position = New Vector4(X2, Y1, z, 0)
        '    aLineVertex(1).Color = colour.ToArgb

        '    aLineVertex(2).Position = New Vector4(X1, Y2, z, 0)
        '    aLineVertex(2).Color = colour.ToArgb

        '    aLineVertex(3).Position = New Vector4(X2, Y2, z, 0)
        '    aLineVertex(3).Color = colour.ToArgb

        '    Try

        '        DirectX.D3D.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, aLineVertex)

        '    Catch ex As Microsoft.DirectX.Direct3D.DeviceLostException

        '    Catch ex As Microsoft.DirectX.Direct3D.DeviceNotResetException

        '    End Try

        'End Sub


        'Public Sub DrawBox(ByRef X1 As Single, ByRef X2 As Single, ByRef Y1 As Single, ByRef Y2 As Single, ByRef Width As Single, ByRef Colour As System.Drawing.Color)

        'Dim aLineVectors(1) As Microsoft.DirectX.Vector2

        'DirectX.Line.Width = Width

        'DirectX.Line.Begin()

        'aLineVectors(0).X = X1 - 0.5
        'aLineVectors(0).Y = Y1 '+ 0.5

        'aLineVectors(1).X = X2 + 0.5
        'aLineVectors(1).Y = Y1 '+ 0.5

        'DirectX.Line.Draw(aLineVectors, Colour)

        'aLineVectors(0).X = X2 '- 0.5
        'aLineVectors(0).Y = Y1 '+ 0.5

        'aLineVectors(1).X = X2 '+ 0.5
        'aLineVectors(1).Y = Y2 '+ 0.5

        'DirectX.Line.Draw(aLineVectors, Colour)

        'aLineVectors(0).X = X1 - 0.5
        'aLineVectors(0).Y = Y2 '+ 0.5

        'aLineVectors(1).X = X2 + 0.5
        'aLineVectors(1).Y = Y2 '+ 0.5

        'DirectX.Line.Draw(aLineVectors, Colour)

        'aLineVectors(0).X = X1 '- 0.5
        'aLineVectors(0).Y = Y1 '+ 0.5

        'aLineVectors(1).X = X1 '+ 0.5
        'aLineVectors(1).Y = Y2 '+ 0.5

        'DirectX.Line.Draw(aLineVectors, Colour)

        'aLineVectors(2).X = X2 '+ 0.5
        'aLineVectors(2).Y = Y2 '+ 0.5

        'aLineVectors(3).X = X1 '+ 0.5
        'aLineVectors(3).Y = Y2 '+ 0.5

        'aLineVectors(4).X = X1 '+ 0.5
        'aLineVectors(4).Y = Y1 '+ 0.5

        'DirectX.Line.Draw(aLineVectors, Colour)

        'DirectX.Line.End()

        'End Sub
        ' 
        'Dim prevmode As Globals.DrawingMode = Globals.DrawingMode.Normal
        'Dim prevblend As Single = 1.0
        'Dim prevtint As Integer = -1

        'Dim restoremode As Globals.DrawingMode = Globals.DrawingMode.Normal
        'Dim restoreblend As Single = 1.0
        'Dim restoretint As Integer = -1

        'Public Sub RestorePrevDrawMode()
        'SetDrawMode(restoremode, restoreblend, restoretint)
        'End Sub

        Public Sub UseLineShader()
            If DirectX.bUsePixelShaders Then
                DirectX.D3D.PixelShader = Nothing
                DirectX.D3D.SetTextureStageState(0, TextureStageStates.AlphaOperation, TextureOperation.Disable)
                DirectX.D3D.SetTextureStageState(0, TextureStageStates.ColorOperation, TextureOperation.Disable)
            Else
                DirectX.D3D.SetTextureStageState(0, TextureStageStates.AlphaOperation, TextureOperation.Disable)
                DirectX.D3D.SetTextureStageState(0, TextureStageStates.ColorOperation, TextureOperation.Disable)
            End If
        End Sub

        Public Sub ResetShader()
            'SetDrawMode(prevmode, prevblend, prevtint, True)
            'If Not DirectX.bUsePixelShaders Then
            DirectX.D3D.SetTextureStageState(0, TextureStageStates.AlphaOperation, TextureOperation.Modulate)
            DirectX.D3D.SetTextureStageState(0, TextureStageStates.ColorOperation, TextureOperation.SelectArg1)
            'End If
        End Sub

        'Public Sub SetDrawMode(ByRef mode As Globals.DrawingMode, Optional ByRef blendconst As Single = 1.0, Optional ByRef tintcolor As Integer = -1, Optional ByRef reset As Boolean = False)
        'Exit Sub

        'If prevmode = mode And prevblend = blendconst And prevtint = tintcolor And Not reset Then Exit Sub

        'If Not reset Then
        'Debug.Print("Sprite Reset")
        'DirectX.GameSprite.End()
        'DirectX.GameSprite.Begin(SpriteFlags.AlphaBlend)
        'End If

        'restoremode = prevmode
        'restoreblend = prevblend
        'restoretint = prevtint

        'prevmode = mode
        'prevblend = blendconst
        'prevtint = tintcolor

        'Select Case mode

        'Case Globals.DrawingMode.Normal
        'DirectX.sbNormal.Apply()
        'SetDrawModeNormal(blendconst, Color.FromArgb(tintcolor))

        'Case Globals.DrawingMode.Magic
        'DirectX.sbMagic.Apply()
        'SetDrawModeMagic(blendconst, Color.FromArgb(tintcolor))

        'Case Globals.DrawingMode.Grayscale
        'DirectX.sbGray.Apply()
        'SetDrawModeGrayscale(blendconst, Color.FromArgb(tintcolor))

        'Case Globals.DrawingMode.Tinted
        'DirectX.sbGray.Apply()
        'SetDrawModeTinted(blendconst, Color.FromArgb(tintcolor))

        'End Select

        'End Sub

        Private Sub SetPixelShader(ByRef ps As PixelShader)
            'If Not DirectX.D3D.PixelShader Is ps Then
            DirectX.D3D.PixelShader = ps
            'End If
        End Sub

        Public Sub SetDrawModeNormal(ByRef blendconst As Single, ByRef tintcolor As Color)

            'If blendconst = 1 Then
            'DirectX.D3D.PixelShader = Nothing
            'Else
            'DirectX.D3D.PixelShader = DirectX.AlphaPixelShader
            'DirectX.D3D.SetPixelShaderConstant(0, New Vector4(1.0, 1.0, 1.0, blendconst))
            'End If
            If DirectX.bUsePixelShaders Then

                'If blendconst = 1.0 And tintcolor = Color.White Then
                'DirectX.D3D.PixelShader = Nothing
                'Else
                SetPixelShader(DirectX.NormalPixelShader)
                DirectX.D3D.SetPixelShaderConstant(0, New Vector4(1.0, 1.0, 1.0, blendconst))
                DirectX.D3D.SetPixelShaderConstant(1, New Vector4(tintcolor.R / 255, tintcolor.G / 255, tintcolor.B / 255, 1.0))
                'End If

            Else


                If blendconst = 1.0 Then

                    DirectX.D3D.TextureState(1).ColorOperation = TextureOperation.Disable

                Else

                    DirectX.D3D.RenderState.TextureFactor = Color.FromArgb(blendconst * 255, 0, 0, 0).ToArgb
                    DirectX.D3D.TextureState(1).ColorOperation = TextureOperation.SelectArg1
                    DirectX.D3D.TextureState(1).ColorArgument1 = TextureArgument.Current
                    DirectX.D3D.TextureState(1).AlphaOperation = TextureOperation.Modulate
                    DirectX.D3D.TextureState(1).AlphaArgument1 = TextureArgument.Current
                    DirectX.D3D.TextureState(1).AlphaArgument2 = TextureArgument.TFactor
                    DirectX.D3D.TextureState(1).ConstantColor = Color.FromArgb(blendconst * 255, 0, 0, 0)
                    DirectX.D3D.TextureState(1).ResultArgument = TextureArgument.Current

                    DirectX.D3D.TextureState(2).ColorOperation = TextureOperation.Disable
                    DirectX.D3D.TextureState(2).AlphaOperation = TextureOperation.Disable

                End If

            End If

        End Sub

        Public Sub SetDrawModeMagic(ByRef blendconst As Single, ByRef tintcolor As Color)


            If DirectX.bUsePixelShaders Then

                SetPixelShader(DirectX.MagicPixelShader)
                DirectX.D3D.SetPixelShaderConstant(0, New Vector4(1.0, 1.0, 1.0, blendconst))
                DirectX.D3D.SetPixelShaderConstant(1, New Vector4(tintcolor.R / 255, tintcolor.G / 255, tintcolor.B / 255, 1.0))
                'DirectX.D3D.PixelShader = DirectX.MagicPixelShader
                'DirectX.D3D.SetPixelShaderConstant(0, New Vector4(1.0, 1.0, 1.0, blendconst))

            Else

                'texture factor for luminance
                DirectX.D3D.RenderState.TextureFactor = (255 << 24) Or ((255 - 29) << 16) Or ((255 - 150) << 8) Or (255 - 76)

                DirectX.D3D.TextureState(1).ColorOperation = TextureOperation.AddSmooth
                DirectX.D3D.TextureState(1).ColorArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(1).ColorArgument2 = TextureArgument.Constant
                DirectX.D3D.TextureState(1).AlphaOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(1).AlphaArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(1).ResultArgument = TextureArgument.Temp
                DirectX.D3D.TextureState(1).ConstantColor = Color.Gray

                DirectX.D3D.TextureState(2).ColorOperation = TextureOperation.DotProduct3
                DirectX.D3D.TextureState(2).ColorArgument1 = TextureArgument.Temp
                DirectX.D3D.TextureState(2).ColorArgument2 = TextureArgument.TFactor
                DirectX.D3D.TextureState(2).AlphaOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(2).AlphaArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(2).ResultArgument = TextureArgument.Temp

                DirectX.D3D.TextureState(3).ColorOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(3).ColorArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(3).AlphaOperation = TextureOperation.Subtract
                DirectX.D3D.TextureState(3).AlphaArgument1 = TextureArgument.Temp
                DirectX.D3D.TextureState(3).AlphaArgument2 = TextureArgument.Constant
                DirectX.D3D.TextureState(3).ConstantColor = Color.FromArgb((1.0 - blendconst) * 255, 0, 0, 0)
                DirectX.D3D.TextureState(3).ResultArgument = TextureArgument.Current

                If tintcolor.A = 0 Then
                    DirectX.D3D.TextureState(4).ColorOperation = TextureOperation.Disable
                    DirectX.D3D.TextureState(4).AlphaOperation = TextureOperation.Disable
                Else
                    DirectX.D3D.TextureState(4).ColorOperation = TextureOperation.Modulate
                    DirectX.D3D.TextureState(4).ColorArgument1 = TextureArgument.Current
                    DirectX.D3D.TextureState(4).ColorArgument2 = TextureArgument.Constant
                    DirectX.D3D.TextureState(4).ConstantColor = tintcolor
                    DirectX.D3D.TextureState(4).AlphaOperation = TextureOperation.SelectArg1
                    DirectX.D3D.TextureState(4).AlphaArgument1 = TextureArgument.Current
                    DirectX.D3D.TextureState(4).ResultArgument = TextureArgument.Current

                    DirectX.D3D.TextureState(5).ColorOperation = TextureOperation.Disable
                    DirectX.D3D.TextureState(5).AlphaOperation = TextureOperation.Disable
                End If

            End If

        End Sub

        Public Sub SetDrawModeLights(ByRef blendconst As Single, ByRef tintcolor As Color)


            If DirectX.bUsePixelShaders Then

                SetPixelShader(DirectX.MagicPixelShader)
                DirectX.D3D.SetPixelShaderConstant(0, New Vector4(1.0, 1.0, 1.0, blendconst))
                DirectX.D3D.SetPixelShaderConstant(1, New Vector4(tintcolor.R / 255, tintcolor.G / 255, tintcolor.B / 255, 1.0))
                'DirectX.D3D.PixelShader = DirectX.MagicPixelShader
                'DirectX.D3D.SetPixelShaderConstant(0, New Vector4(1.0, 1.0, 1.0, blendconst))

            Else

                'texture factor for luminance
                DirectX.D3D.RenderState.TextureFactor = (255 << 24) Or ((255 - 29) << 16) Or ((255 - 150) << 8) Or (255 - 76)

                DirectX.D3D.TextureState(1).ColorOperation = TextureOperation.AddSmooth
                DirectX.D3D.TextureState(1).ColorArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(1).ColorArgument2 = TextureArgument.Constant
                DirectX.D3D.TextureState(1).AlphaOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(1).AlphaArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(1).ResultArgument = TextureArgument.Temp
                DirectX.D3D.TextureState(1).ConstantColor = Color.FromArgb(255, 148, 148, 148)

                DirectX.D3D.TextureState(2).ColorOperation = TextureOperation.DotProduct3
                DirectX.D3D.TextureState(2).ColorArgument1 = TextureArgument.Temp
                DirectX.D3D.TextureState(2).ColorArgument2 = TextureArgument.TFactor
                DirectX.D3D.TextureState(2).AlphaOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(2).AlphaArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(2).ResultArgument = TextureArgument.Temp

                DirectX.D3D.TextureState(3).ColorOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(3).ColorArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(3).AlphaOperation = TextureOperation.Subtract
                DirectX.D3D.TextureState(3).AlphaArgument1 = TextureArgument.Constant
                DirectX.D3D.TextureState(3).AlphaArgument2 = TextureArgument.Temp
                DirectX.D3D.TextureState(3).ConstantColor = Color.FromArgb(blendconst * 255, 0, 0, 0)
                DirectX.D3D.TextureState(3).ResultArgument = TextureArgument.Temp

                DirectX.D3D.TextureState(4).ColorOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(4).ColorArgument1 = TextureArgument.Constant
                DirectX.D3D.TextureState(4).ConstantColor = tintcolor
                DirectX.D3D.TextureState(4).AlphaOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(4).AlphaArgument1 = TextureArgument.Temp
                DirectX.D3D.TextureState(4).ResultArgument = TextureArgument.Current

                DirectX.D3D.TextureState(5).ColorOperation = TextureOperation.Disable
                DirectX.D3D.TextureState(5).AlphaOperation = TextureOperation.Disable

            End If

        End Sub

        Public Sub SetDrawModeGrayscale(ByRef blendconst As Single, ByRef tintcolor As Color)

            If DirectX.bUsePixelShaders Then

                SetPixelShader(DirectX.GrayScalePixelShader)
                DirectX.D3D.SetPixelShaderConstant(0, New Vector4(1.0, 1.0, 1.0, blendconst))
                DirectX.D3D.SetPixelShaderConstant(1, New Vector4(tintcolor.R / 255, tintcolor.G / 255, tintcolor.B / 255, 1.0))

            Else

                'texture factor for luminance
                DirectX.D3D.RenderState.TextureFactor = (255 << 24) Or ((255 - 29) << 16) Or ((255 - 150) << 8) Or (255 - 76)

                DirectX.D3D.TextureState(1).ColorOperation = TextureOperation.AddSmooth
                DirectX.D3D.TextureState(1).ColorArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(1).ColorArgument2 = TextureArgument.Constant
                DirectX.D3D.TextureState(1).AlphaOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(1).AlphaArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(1).ResultArgument = TextureArgument.Temp
                DirectX.D3D.TextureState(1).ConstantColor = Color.Gray

                DirectX.D3D.TextureState(2).ColorOperation = TextureOperation.DotProduct3
                DirectX.D3D.TextureState(2).ColorArgument1 = TextureArgument.Temp
                DirectX.D3D.TextureState(2).ColorArgument2 = TextureArgument.TFactor
                DirectX.D3D.TextureState(2).AlphaOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(2).AlphaArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(2).ResultArgument = TextureArgument.Temp

                DirectX.D3D.TextureState(3).ColorOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(3).ColorArgument1 = TextureArgument.Temp
                DirectX.D3D.TextureState(3).AlphaOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(3).AlphaArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(3).ResultArgument = TextureArgument.Current

                DirectX.D3D.TextureState(4).ColorOperation = TextureOperation.Disable
                DirectX.D3D.TextureState(4).AlphaOperation = TextureOperation.Disable

            End If

        End Sub

        Public Sub SetDrawModeLightsTex(ByRef blendconst As Single, ByRef tintcolor As Color)

            If DirectX.bUsePixelShaders Then

                SetPixelShader(DirectX.GrayScalePixelShader)
                DirectX.D3D.SetPixelShaderConstant(0, New Vector4(1.0, 1.0, 1.0, blendconst))
                DirectX.D3D.SetPixelShaderConstant(1, New Vector4(tintcolor.R / 255, tintcolor.G / 255, tintcolor.B / 255, 1.0))

            Else

                'texture factor for luminance
                DirectX.D3D.RenderState.TextureFactor = (255 << 24) Or ((255 - 29) << 16) Or ((255 - 150) << 8) Or (255 - 76)

                DirectX.D3D.TextureState(1).ColorOperation = TextureOperation.AddSmooth
                DirectX.D3D.TextureState(1).ColorArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(1).ColorArgument2 = TextureArgument.Constant
                DirectX.D3D.TextureState(1).AlphaOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(1).AlphaArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(1).ResultArgument = TextureArgument.Temp
                DirectX.D3D.TextureState(1).ConstantColor = Color.FromArgb(255, 128, 128, 128)

                DirectX.D3D.TextureState(2).ColorOperation = TextureOperation.DotProduct3
                DirectX.D3D.TextureState(2).ColorArgument1 = TextureArgument.Temp
                DirectX.D3D.TextureState(2).ColorArgument2 = TextureArgument.TFactor
                DirectX.D3D.TextureState(2).AlphaOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(2).AlphaArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(2).ResultArgument = TextureArgument.Temp

                DirectX.D3D.TextureState(3).ColorOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(3).ColorArgument1 = TextureArgument.Constant
                DirectX.D3D.TextureState(3).AlphaOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(3).AlphaArgument1 = TextureArgument.Temp
                DirectX.D3D.TextureState(3).ConstantColor = Color.White
                DirectX.D3D.TextureState(3).ResultArgument = TextureArgument.Current

                DirectX.D3D.TextureState(4).ColorOperation = TextureOperation.Disable
                DirectX.D3D.TextureState(4).AlphaOperation = TextureOperation.Disable

            End If

        End Sub

        Public Sub SetDrawModeShadow(ByRef blendconst As Single)

            If DirectX.bUsePixelShaders Then

                SetPixelShader(DirectX.ShadowPixelShader)

                DirectX.D3D.SetPixelShaderConstant(0, New Vector4(1.0, 1.0, 1.0, blendconst))

            Else

                'texture factor for luminance

                DirectX.D3D.TextureState(1).ColorOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(1).ColorArgument1 = TextureArgument.Constant
                DirectX.D3D.TextureState(1).AlphaOperation = TextureOperation.Modulate
                DirectX.D3D.TextureState(1).AlphaArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(1).AlphaArgument2 = TextureArgument.Constant
                DirectX.D3D.TextureState(1).ResultArgument = TextureArgument.Current
                DirectX.D3D.TextureState(1).ConstantColor = Color.FromArgb(255 * blendconst, 0, 0, 0)

                DirectX.D3D.TextureState(2).ColorOperation = TextureOperation.Disable
                DirectX.D3D.TextureState(2).AlphaOperation = TextureOperation.Disable

            End If

        End Sub

        Public Sub SetDrawModeTinted(ByRef blendconst As Single, ByRef tintcolor As Color)

            If DirectX.bUsePixelShaders Then

                SetPixelShader(DirectX.GrayScalePixelShader)
                DirectX.D3D.SetPixelShaderConstant(0, New Vector4(1.0, 1.0, 1.0, blendconst))
                DirectX.D3D.SetPixelShaderConstant(1, New Vector4(tintcolor.R / 255, tintcolor.G / 255, tintcolor.B / 255, 1.0))
                'DirectX.D3D.PixelShader = DirectX.TintPixelShader
                'DirectX.D3D.SetPixelShaderConstant(0, New Vector4(1.0, 1.0, 1.0, blendconst))

                DirectX.D3D.TextureState(1).ColorOperation = TextureOperation.Disable
                DirectX.D3D.TextureState(1).AlphaOperation = TextureOperation.Disable

            Else

                'texture factor for luminance
                DirectX.D3D.RenderState.TextureFactor = (255 << 24) Or ((255 - 29) << 16) Or ((255 - 150) << 8) Or (255 - 76)

                DirectX.D3D.TextureState(1).ColorOperation = TextureOperation.AddSmooth
                DirectX.D3D.TextureState(1).ColorArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(1).ColorArgument2 = TextureArgument.Constant
                DirectX.D3D.TextureState(1).AlphaOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(1).AlphaArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(1).ResultArgument = TextureArgument.Temp
                DirectX.D3D.TextureState(1).ConstantColor = Color.Gray

                DirectX.D3D.TextureState(2).ColorOperation = TextureOperation.DotProduct3
                DirectX.D3D.TextureState(2).ColorArgument1 = TextureArgument.Temp
                DirectX.D3D.TextureState(2).ColorArgument2 = TextureArgument.TFactor
                DirectX.D3D.TextureState(2).AlphaOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(2).AlphaArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(2).ResultArgument = TextureArgument.Temp

                DirectX.D3D.TextureState(3).ColorOperation = TextureOperation.Modulate
                DirectX.D3D.TextureState(3).ColorArgument1 = TextureArgument.Constant
                DirectX.D3D.TextureState(3).ColorArgument2 = TextureArgument.Temp
                DirectX.D3D.TextureState(3).ConstantColor = tintcolor
                DirectX.D3D.TextureState(3).AlphaOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(3).AlphaArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(3).ResultArgument = TextureArgument.Temp

                DirectX.D3D.TextureState(4).ColorOperation = TextureOperation.SelectArg1
                DirectX.D3D.TextureState(4).ColorArgument1 = TextureArgument.Temp
                DirectX.D3D.TextureState(4).AlphaOperation = TextureOperation.Modulate
                DirectX.D3D.TextureState(4).AlphaArgument1 = TextureArgument.Current
                DirectX.D3D.TextureState(4).AlphaArgument2 = TextureArgument.Constant
                DirectX.D3D.TextureState(4).ConstantColor = Color.FromArgb(blendconst * 255, 0, 0, 0)
                DirectX.D3D.TextureState(4).ResultArgument = TextureArgument.Current

                DirectX.D3D.TextureState(5).ColorOperation = TextureOperation.Disable
                DirectX.D3D.TextureState(5).AlphaOperation = TextureOperation.Disable

            End If

        End Sub

        Private Function AppIsIdle() As Boolean
            Static msg As MessageStruct
            Return (PeekMessage(msg, Globals.fGameForm.Handle, 0, 0, 0) = 0)
        End Function


    End Module

End Namespace